package com.crois.barrier.web.handler;

import com.crois.barrier.common.constants.Constants;
import com.crois.barrier.common.dto.ApiRouteInfo;
import com.crois.barrier.web.cache.CacheManager;
import com.crois.barrier.web.spring.SpringBeanUtils;
import com.crois.barrier.web.support.ServerWebExchangeUtils;
import com.zhimydou.ztools.collection.CollectionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.web.server.ServerWebExchange;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Hou Ze Yu
 * @description Url 处理
 * @date 2020/7/19
 */
public class UrlHandler {

    private static final String DEFAULT_PATH = "/**";

    private static Logger LOGGER = LoggerFactory.getLogger(UrlHandler.class);

    private static AntPathMatcher antPathMatcher =new AntPathMatcher();


    /***
     * 判断路径 是否 匹配
     * @param cacheManager
     * @param requestPath
     * @param serverWebExchange
     * @return
     */
    public static Boolean judgeIsMatch(CacheManager cacheManager, String requestPath, ServerWebExchange serverWebExchange) {
        // 得到 全部 已发布 api 列表
        List<ApiRouteInfo> apiRouteInfoList = cacheManager.apiRouteInfoList();

        // 是否 匹配
        if (!CollectionUtils.isEmpty(apiRouteInfoList)){

            List<ApiRouteInfo>  preMatchApiRouteInfoList =new ArrayList<>();
            for (ApiRouteInfo apiRouteInfo : apiRouteInfoList) {
                String path = apiRouteInfo.getRequestPath();
                Integer matchType = apiRouteInfo.getMatchType();
                if (matchType.equals(Constants.PRECISE_MATCH_TYPE)){
                         if (path.equals(requestPath)){
                             // 只要匹配到 直接 返回
                             preMatchApiRouteInfoList.add(apiRouteInfo);
                             LOGGER.info("【match api route success】  path:{}, api route:{}",requestPath,apiRouteInfo);

                         }
                }else if (matchType.equals(Constants.FUZZY_MATCH_TYPE)){

                    if (antPathMatcher.match(path+DEFAULT_PATH, String.valueOf(requestPath))){

                        preMatchApiRouteInfoList.add(apiRouteInfo);

                        LOGGER.info("【match api route success】  path:{}, api route:{}",requestPath,apiRouteInfo);

                    }
                }
            }
            if (CollectionUtil.isNotEmpty(preMatchApiRouteInfoList)){

                WeightRoundRobinApiRouteMatchHandler weightRoundRobinApiRouteMatchHandler = SpringBeanUtils.getInstance().getBean(WeightRoundRobinApiRouteMatchHandler.class);

                ApiRouteInfo checkedApiRouteInfo = weightRoundRobinApiRouteMatchHandler.choose(preMatchApiRouteInfoList,requestPath);
                if (checkedApiRouteInfo.getTimeout()!=null){
                    serverWebExchange.getAttributes().put(ServerWebExchangeUtils.HTTP_TIME_OUT,checkedApiRouteInfo.getTimeout());
                }
                if (checkedApiRouteInfo.getRetry()!=null){
                    serverWebExchange.getAttributes().put(ServerWebExchangeUtils.RETRY_TIMES,checkedApiRouteInfo.getRetry());
                }
                serverWebExchange.getAttributes().put(ServerWebExchangeUtils.BARRIER_ROUTE_ATTR,checkedApiRouteInfo);
                 return true;
            }
        }
        LOGGER.warn("【not match api route】 path:{}, not match available api route",requestPath);
        return false;
    }
}
